package cn.kmsoft.stgeometry.util;

import cn.kmsoft.common.exception.ExceptionMsg;
import cn.kmsoft.common.exception.ServiceException;
import cn.kmsoft.wololo.object.GeoJsonFeature;
import cn.kmsoft.wololo.object.GeoJsonGeometry;
import com.alibaba.druid.proxy.jdbc.ClobProxyImpl;
import com.alibaba.fastjson.JSONObject;
import oracle.sql.CLOB;

import java.io.BufferedReader;
import java.io.Reader;
import java.sql.SQLException;
import java.util.*;

/**
 * @author
 * @date
 */
public class GeoJsonUtil {
    private static final String GEO_FIELD = "GEOQ_GEOM";
    private static final String DB_GEO_FIELD = "SHAPE";
    private static final String EMPTY_GEO_FIELD = "EMPTY";

    /**
     * 转换结果为GeoJson
     *
     * @param results 查询结果
     * @return GeoJson
     */
    public static List<GeoJsonFeature> parse(List<Map<String, Object>> results, int wkid) {
        List<GeoJsonFeature> outFeatures = new ArrayList<>();
        //results.forEach(item -> outFeatures.add(parse(item, wkid)));
        Iterator<Map<String, Object>> iter = results.iterator();
        while( iter.hasNext() ){
            Map<String, Object> res = iter.next();
            GeoJsonFeature fea = parse(res,wkid);
            if(fea.getGeometry()!=null) {
                outFeatures.add(fea);
            }
        }

        return outFeatures;
    }

    public static GeoJsonFeature parse(Map<String, Object> result, int wkid) {
        GeoJsonFeature outFeature = new GeoJsonFeature();
        outFeature.setType("Feature");

        Map<String, Object> outProperties = new HashMap<>();
        Set<String> keySet = result.keySet();
        Iterator<String> keyIter = keySet.iterator();
        while(keyIter.hasNext()){
            String key = keyIter.next();
            if (!key.toUpperCase().startsWith(DB_GEO_FIELD)) {
                if (key.equalsIgnoreCase(GEO_FIELD)) {
                    if( result.get(key) != null ){
                        CLOB geo = (CLOB) ((ClobProxyImpl) result.get(key)).getRawClob();
                        try {
                            if (!geo.stringValue().equalsIgnoreCase(EMPTY_GEO_FIELD)) {
                                GeoJsonGeometry geometry = JSONObject.parseObject(GeomUtil.wktToGeoJson(geo.stringValue(), wkid), GeoJsonGeometry.class);
                                outFeature.setGeometry(geometry);
                            }else{
                                outFeature.setGeometry(null);
                            }
                        } catch (SQLException e) {
                            throw new ServiceException(ExceptionMsg.SYSTEM_ERROR, "failed to get geometry from clob");
                        }
                    }
                } else {
                    outProperties.put(key, result.get(key) != null && !(result.get(key) instanceof Number) ? result.get(key).toString() : result.get(key));
                }
            }
        }

        outFeature.setProperties(outProperties);
        return outFeature;
    }

    public static String clobToString(CLOB clob) throws Exception{
        String res="";
        if( clob !=null && clob.getCharacterStream()!=null){
            Reader io=clob.getCharacterStream();
            BufferedReader br=new BufferedReader(io);
            String s=br.readLine();
            StringBuffer sb=new StringBuffer();
            while(s !=null ){
                sb.append(s);
                s=br.readLine();
            }
            res=sb.toString();
        }
        return res;
    }
}
